/*
* Copyright(C) NXP Semiconductors, 2011
* All rights reserved.
*
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* LPC products.  This software is supplied "AS IS" without any warranties of
* any kind, and NXP Semiconductors and its licensor disclaim any and 
* all warranties, express or implied, including all implied warranties of 
* merchantability, fitness for a particular purpose and non-infringement of 
* intellectual property rights.  NXP Semiconductors assumes no responsibility
* or liability for the use of the software, conveys no license or rights under any
* patent, copyright, mask work right, or any other intellectual property rights in 
* or to any products. NXP Semiconductors reserves the right to make changes
* in the software without notification. NXP Semiconductors also makes no 
* representation or warranty that such application will be suitable for the
* specified use without further testing or modification.
* 
* Permission to use, copy, modify, and distribute this software and its 
* documentation is hereby granted, under NXP Semiconductors' and its 
* licensor's relevant copyrights in the software, without fee, provided that it 
* is used in conjunction with NXP Semiconductors microcontrollers.  This 
* copyright, permission, and disclaimer notice must appear in all copies of 
* this code.
*/

#define  __INCLUDE_FROM_USB_DRIVER
#include "../../USBMode.h"

#ifdef USB_CAN_BE_HOST

#if !defined(__LPC_OHCI__) && !defined(__LPC_EHCI__)
	#error "Either __LPC_OHCI__ or __LPC_EHCI__ must be defined"
#endif

#include "../../USBTask.h"

/*==========================================================================*/
/* Private Functions to OHCI EHCI                        											*/
/*==========================================================================*/

#ifdef LPCUSBlib_DEBUG
void assert_status_ok_message(HCD_STATUS status, char const * mess, char const * func, char const * file, uint32_t const line )
{
	if (HCD_STATUS_OK != status)
	{
		hcd_printf("%s\r\n", func);
		hcd_printf("\t%s: %d\r\n", file, line);
		hcd_printf("\tEvaluated HCD_STATUS = %d\r\n", (uint32_t)status );
		if (mess != NULL){
			hcd_printf("\t%s\r\n", mess);
		}
	}
}
#endif

void  HcdDelayUS (uint32_t  delay)
{
	volatile  uint32_t  i;

	for (i = 0; i < (4 * delay); i++) {    /* This logic was tested. It gives app. 1 micro sec delay        */
		;
	}
}
void  HcdDelayMS (uint32_t  delay)
{
	volatile  uint32_t  i;

	for (i = 0; i < delay; i++) {
		HcdDelayUS(1000);
	}
}

HCD_STATUS OpenPipe_VerifyParameters( uint8_t HostID, uint8_t DeviceAddr, HCD_USB_SPEED DeviceSpeed, uint8_t EndpointNumber, HCD_TRANSFER_TYPE TransferType, HCD_TRANSFER_DIR TransferDir, uint16_t MaxPacketSize, uint8_t Interval, uint8_t Mult )
{
	if	(HostID >= MAX_USB_CORE ||
		DeviceAddr > 127 ||
		DeviceSpeed > HIGH_SPEED ||
		(EndpointNumber & 0x70) ||
		TransferType > INTERRUPT_TRANSFER ||
		TransferDir > OUT_TRANSFER )
	{
		ASSERT_STATUS_OK(HCD_STATUS_PARAMETER_INVALID);
	}

	/* XXX by USB specs Low speed device should not have packet size > 8, but many market devices does */
	if (DeviceSpeed == LOW_SPEED && (TransferType == BULK_TRANSFER || TransferType == ISOCHRONOUS_TRANSFER ) )
	{
		ASSERT_STATUS_OK(HCD_STATUS_PARAMETER_INVALID);
	}

	switch(TransferType)
	{
	case CONTROL_TRANSFER:
		if (MaxPacketSize > 64)
		{
			ASSERT_STATUS_OK(HCD_STATUS_PARAMETER_INVALID);
		}
		break;

	case BULK_TRANSFER:
		if ((DeviceSpeed == FULL_SPEED && MaxPacketSize > 64) ||
			(DeviceSpeed == HIGH_SPEED && MaxPacketSize > 512) )
		{
			ASSERT_STATUS_OK(HCD_STATUS_PARAMETER_INVALID);
		}
		break;

	case INTERRUPT_TRANSFER:
		if ( Interval==0 ||
			(DeviceSpeed == FULL_SPEED && MaxPacketSize > 64) ||
			(DeviceSpeed == HIGH_SPEED && (MaxPacketSize > 1024 || Interval > 16 || Mult == 0)) )
		{
			ASSERT_STATUS_OK(HCD_STATUS_PARAMETER_INVALID);
		}
		break;

	case ISOCHRONOUS_TRANSFER:
		if ( Interval == 0 || Interval > 16 ||
			(DeviceSpeed == FULL_SPEED && MaxPacketSize > 1023) ||
			(DeviceSpeed == HIGH_SPEED && (MaxPacketSize > 1024 || Mult == 0)) )
		{
			ASSERT_STATUS_OK(HCD_STATUS_PARAMETER_INVALID);
		}
		break;
	}
	return HCD_STATUS_OK;
}

#endif
